package com.atguigu.juc.cf;

import org.junit.jupiter.api.Test;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * @author yanglin
 * @create 2024-01-05 10:23 星期五
 * description:
 */
public class CompletableFutureWithThreadPoolDemo {


    /**
     * 总结：
     *  没有传入自定义线程池，都用默认的线程池ForkJoinPool
     *  传入了一个自定义线程池：
     *      调用thenRun方法执行第二个任务时，则第二个任务和第一个任务是共用一个线程池
     *      调用thenRunAsync执行第二个任务时，则第一个任务使用的是自己传入的线程池，第二个任务使用的时ForkJoinPool
     *      
     *  备注：
     *      有可能处理太快，系统优化切换原则，直接使用main线程
     */
    @Test
    public void testCompletableFutureWithThreadPool(){
        
        ExecutorService threadPool = Executors.newFixedThreadPool(3);
        try {
            CompletableFuture<Void> completableFuture = CompletableFuture.supplyAsync(() -> {
                try {
                    TimeUnit.MILLISECONDS.sleep(20);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("1号任务" + "\t" + Thread.currentThread().getName());
                return "abcd";
            },threadPool).thenRunAsync(() -> {
                try {
                    TimeUnit.MILLISECONDS.sleep(20);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("2号任务" + "\t" + Thread.currentThread().getName());
            }).thenRunAsync(() -> {
                try {
                    TimeUnit.MILLISECONDS.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("3号任务" + "\t" + Thread.currentThread().getName());
            }).thenRunAsync(() -> {
                try {
                    TimeUnit.MILLISECONDS.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("4号任务" + "\t" + Thread.currentThread().getName());
            });
            
            completableFuture.get(2,TimeUnit.SECONDS);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            threadPool.shutdown();
        }
    }
    
}
